package com.weishi.project.dataview.service.impl;

import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.weishi.common.utils.DateUtils;
import com.weishi.common.utils.StringUtils;
import com.weishi.project.api.vo.InjuryCountVo;
import com.weishi.project.api.vo.TrainingAchievementTopVo;
import com.weishi.project.api.vo.TrainingDayDetailsVo;
import com.weishi.project.api.vo.TrainingDayWeekOrDayVo;
import com.weishi.project.dataview.service.IDataViewService;
import com.weishi.project.system.domain.SysDictData;
import com.weishi.project.system.service.ISysDictDataService;
import com.weishi.project.training.domain.*;
import com.weishi.project.training.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class IDataViewServiceImpl implements IDataViewService {

    @Autowired
    private ISportsmanService sportsmanService;

    private JSONObject weather = null;

    @Autowired
    private ILeaveFormService leaveFormService;

    @Autowired
    private ISportsmanMatchService sportsmanMatchService;

    @Autowired
    private ITrainingDayService trainingDayService;

    @Autowired
    private INaturalYearService naturalYearService;

    @Autowired
    private ISysDictDataService sysDictDataService;

    @Autowired
    private ITrainingAchievementService trainingAchievementService;

    @Autowired
    private IAnnualPlanService annualPlanService;

    @Autowired
    private IAnnualProjectService annualProjectService;


    /**
     * 获取最新天气
     */
    @Scheduled(cron = "0 0 */1 * * ?")
    public void getWeatherNow() {
        try {
            String ret = HttpUtil.get("https://devapi.qweather.com/v7/weather/now?key=355bef5275044099a0bff5de3dc9894c&location=117.1,28.6");
            weather = JSONUtil.parseObj(ret);
        } catch (Exception e) {
            weather = null;
            e.printStackTrace();
        }
    }

    @Override
    public JSONObject getWeather(int teamId) {
        if (weather == null) {
            getWeatherNow();
        }

        return weather;
    }

    @Override
    public Map<String, Object> getTeamPeopleTotal(int teamId) {
        Sportsman params = new Sportsman();
        List<Sportsman> list = sportsmanService.selectSportsmanList(params);
        int training = 0, male = 0, female = 0;
        for (Sportsman sportsman : list) {
            if (sportsman.getStatus().equals("0") || sportsman.getStatus().equals("2")) {
                training++;
            }
            if (sportsman.getSex() == 0) {
                male++;
            } else {
                female++;
            }
        }
        Map<String, Object> teamPeople = new HashMap<>();
        teamPeople.put("teamId", 1);
        teamPeople.put("teamName", "赛艇队");
        teamPeople.put("total", list.size());
        teamPeople.put("training", training);
        teamPeople.put("trial", 0);
        teamPeople.put("male", male);
        teamPeople.put("female", female);
        return teamPeople;
    }

    @Override
    public Map<String, Object> getTeamPeopleStatus(int teamId) {
        List<Map<String, Object>> list = sportsmanService.selectSportsmanCountByType();
        Map<String, Object> teamStatus = new HashMap<>();
        long outsideTraining = 0, sick = 0, leave = 0, injury = 0;
        for (Map<String, Object> map : list) {
            if (map.get("status").equals("2")) {
                outsideTraining += (long) map.get("num");
            }
            if (map.get("status").equals("3")) {
                leave += (long) map.get("num");
            }
            if (map.get("status").equals("4")) {
                sick += (long) map.get("num");
            }
            if (map.get("status").equals("5") || map.get("status").equals("6")) {
                injury += (long) map.get("num");
            }
        }
        teamStatus.put("teamId", 1);
        teamStatus.put("teamName", "赛艇队");
        teamStatus.put("sick", sick);
        teamStatus.put("leave", leave);
        teamStatus.put("outsideTraining", outsideTraining);
        teamStatus.put("injured", injury);
        return teamStatus;
    }

    @Override
    public Map<String, Object> getTeamInjuredStatus(int teamId) {
        Map<String, Object> teamInjuredStatus = new HashMap<>();
        teamInjuredStatus.put("teamId", 1);
        teamInjuredStatus.put("teamName", "赛艇队");
        teamInjuredStatus.put("upperLimbs", 0);
        teamInjuredStatus.put("lowerLimbs", 0);
        teamInjuredStatus.put("trunk", 0);
        teamInjuredStatus.put("spine", 0);

        Map<String, Object> params = new HashMap<>();
        params.put("type", 5);
        params.put("askingForLeave", 1);
        List<InjuryCountVo> list = this.leaveFormService.getInjuryCountVoList(params);
        for (InjuryCountVo injuryCountVo : list) {
            if (injuryCountVo.getReason().equals("上肢")) {
                teamInjuredStatus.put("upperLimbs", injuryCountVo.getCount());
            }
            if (injuryCountVo.getReason().equals("下肢")) {
                teamInjuredStatus.put("lowerLimbs", injuryCountVo.getCount());
            }
            if (injuryCountVo.getReason().equals("躯干")) {
                teamInjuredStatus.put("trunk", injuryCountVo.getCount());
            }
            if (injuryCountVo.getReason().equals("颈椎")) {
                teamInjuredStatus.put("spine", injuryCountVo.getCount());
            }
        }
        return teamInjuredStatus;
    }

    @Override
    public List<Map<String, Object>> getCompetitionTarget(int teamId) {
        List<Map<String, Object>> competitionTargetList = new ArrayList<>();
        SportsmanMatch params = new SportsmanMatch();
        List<SportsmanMatch> list = sportsmanMatchService.selectSportsmanMatchList(params);
        for (SportsmanMatch sportsmanMatch : list) {
            Map<String, Object> temp = new HashMap<>();
            temp.put("teamId", 1);
            temp.put("teamName", "赛艇队");
            temp.put("name", sportsmanMatch.getMatchName());
            temp.put("time", DateUtils.parseDateToStr("yyyy-MM-dd", sportsmanMatch.getMatchTime()));
            temp.put("task", sportsmanMatch.getMemo());
            temp.put("countDown", DateUtils.getTimeDifference(sportsmanMatch.getMatchTime(), new Date()));
            competitionTargetList.add(temp);
        }

        return competitionTargetList;
    }

    @Override
    public List<Map<String, Object>> getTrainingTimeList(int teamId) {
        Map<String, Object> params = new HashMap<>();
        NaturalYear naturalYear = naturalYearService.getNaturalYearByDate(new Date());
        params.put("naturalYearId", naturalYear.getId());
        List<TrainingDayWeekOrDayVo> list = trainingDayService.getTrainingDayWeekOrDayVo(params);
        Map<String, Map<String, Object>> tempMap = getTrainingProgram();
        for (TrainingDayWeekOrDayVo vo : list) {
            Map<String, Object> map = tempMap.get(vo.getFirstLevel());
            map.put("value", vo.getRealClassHour());
        }

        List<Map<String, Object>> trainingTimeList = new ArrayList<>();
        for (String key : tempMap.keySet()) {
            Map<String, Object> map = tempMap.get(key);
            trainingTimeList.add(map);
        }
        return trainingTimeList;
    }

    @Override
    public List<Map<String, Object>> getTrainingPlanList(int teamId) {
        int naturalYearId = naturalYearService.getNaturalYearByDate(new Date()).getId();
        //初始化数据
        Map<String, Map<String, Object>> tempMap = getTrainingProgram();

        //获取计划值
        AnnualProject params = new AnnualProject();
        params.setNaturalYearId(naturalYearId);
        List<AnnualProject> annualProjects = annualProjectService.selectAnnualProjectList(params);
        for(AnnualProject annualProject : annualProjects){
            Map<String, Object> map = tempMap.get(annualProject.getFirstLevel());
            map.put("plan",annualProject.getClassHour());
        }

        Map<String, Object> mapParams = new HashMap<>();
        NaturalYear naturalYear = naturalYearService.getNaturalYearByDate(new Date());
        mapParams.put("naturalYearId", naturalYear.getId());
        List<TrainingDayWeekOrDayVo> list = trainingDayService.getTrainingDayWeekOrDayVo(mapParams);

        for (TrainingDayWeekOrDayVo vo : list) {
            Map<String, Object> map = tempMap.get(vo.getFirstLevel());
            map.put("value", vo.getRealClassHour());
        }

        List<Map<String, Object>> trainingTimeList = new ArrayList<>();
        for (String key : tempMap.keySet()) {
            Map<String, Object> map = tempMap.get(key);
            trainingTimeList.add(map);
        }
        return trainingTimeList;
    }

    /**
     * 获取所有一级科目的枚举值
     */
    private Map<String, Map<String, Object>> getTrainingProgram() {
        Map<String, Map<String, Object>> temp = new HashMap<>();
        List<SysDictData> list = sysDictDataService.selectDictDataByType("first_level");
        for (SysDictData sysDictData : list) {
            Map<String, Object> temp1 = new HashMap<>();
            temp1.put("teamId", 1);
            temp1.put("teamName", "赛艇队");
            temp1.put("value", 0);
            temp1.put("name", sysDictData.getDictLabel());
            temp.put(sysDictData.getDictValue(), temp1);
        }
        return temp;
    }

    private List<Map<String, Object>> tableData = new ArrayList<>();

    @Scheduled(cron = "0 */3 * * * ?")
    public void getTrainingAchievementTop3(){
        Map<String, Object> params = new HashMap<>();
        //男子水上专项top3
        params.put("sex", 0);
        NaturalYear naturalYear = naturalYearService.getNaturalYearByDate(new Date());
        params.put("naturalYearId", naturalYear.getId());
        params.put("event", "special_training_water");
        List<TrainingAchievementTopVo> trainingAchievementTopVos = trainingAchievementService.qryTrainingAchievementTop(params);
        for (int i = 0; i < trainingAchievementTopVos.size(); i++) {
            if (StringUtils.isEmpty(trainingAchievementTopVos.get(i).getAchievement())) {
                trainingAchievementTopVos.remove(trainingAchievementTopVos.get(i));
                i--;
            }
        }

        if (trainingAchievementTopVos != null && trainingAchievementTopVos.size() > 3) {
            trainingAchievementTopVos = trainingAchievementTopVos.subList(0, 3);
        }

        for (TrainingAchievementTopVo vo : trainingAchievementTopVos) {
            Map<String, Object> temp3 = new HashMap<>();
            temp3.put("teamId", 1);
            temp3.put("teamName", "赛艇队");
            temp3.put("gender", "男");
            temp3.put("rowBoat", vo.getBoatType());
            temp3.put("name", vo.getName());
            temp3.put("achievement", vo.getAchievement());
            temp3.put("averageFre", vo.getPropellerFrequency());
            tableData.add(temp3);
        }

        //女子水上专项top3
        params.put("sex", 1);
        trainingAchievementTopVos = trainingAchievementService.qryTrainingAchievementTop(params);
        for (int i = 0; i < trainingAchievementTopVos.size(); i++) {
            if (StringUtils.isEmpty(trainingAchievementTopVos.get(i).getAchievement())) {
                trainingAchievementTopVos.remove(trainingAchievementTopVos.get(i));
                i--;
            }
        }

        if (trainingAchievementTopVos != null && trainingAchievementTopVos.size() > 3) {
            trainingAchievementTopVos = trainingAchievementTopVos.subList(0, 3);
        }

        for (TrainingAchievementTopVo vo : trainingAchievementTopVos) {
            Map<String, Object> temp3 = new HashMap<>();
            temp3.put("teamId", 1);
            temp3.put("teamName", "赛艇队");
            temp3.put("gender", "女");
            temp3.put("rowBoat", vo.getBoatType());
            temp3.put("name", vo.getName());
            temp3.put("achievement", vo.getAchievement());
            temp3.put("averageFre", vo.getPropellerFrequency());
            tableData.add(temp3);
        }
    }

    @Override
    public List<Map<String, Object>> getTrainingAchievementTop3(int teamId) {
        return tableData;
    }

    @Override
    public Map<String, Object> getSpecialTrainingTotal(int teamId) {
        Map<String, Map<String, Integer>> temp = new HashMap<>();
        int waterSpecialTotalKil=0;
        int landSpecialTotalKil=0;

        int naturalYearId = naturalYearService.getNaturalYearByDate(new Date()).getId();
        //初始化数据
        AnnualPlan params = new AnnualPlan();
        params.setNaturalYearId(naturalYearId);
        List<AnnualPlan> annualPlans = annualPlanService.selectAnnualPlanList(params);
        for (AnnualPlan annualPlan : annualPlans) {
            Map<String, Integer> map = new HashMap<>();
            map.put("special_training_water", 0);
            map.put("land_specific_training", 0);
            temp.put(annualPlan.getCycleName(), map);
        }

        String firstLevel1 = "special_training_water";
        TrainingDayDetailsVo trainingDayDetailsVo = new TrainingDayDetailsVo();
        trainingDayDetailsVo.setLevel(firstLevel1);
        trainingDayDetailsVo.setNaturalYearId(naturalYearId);
        //水上专项训练
        List<TrainingDayDetailsVo> data1 = trainingDayService.getTrainingDayListDetails(trainingDayDetailsVo);
        for (TrainingDayDetailsVo vo : data1) {
            Map<String, Integer> map = temp.get(vo.getMonth());
            map.put("special_training_water", vo.getCompletionTime());
        }

        String firstLevel2 = "land_specific_training_dynamometer";
        TrainingDayDetailsVo trainingDayDetailsVo2 = new TrainingDayDetailsVo();
        trainingDayDetailsVo2.setLevel(firstLevel2);
        trainingDayDetailsVo2.setNaturalYearId(naturalYearId);
        //陆上专项训练
        List<TrainingDayDetailsVo> data2 = trainingDayService.getTrainingDayListDetails(trainingDayDetailsVo2);
        for (TrainingDayDetailsVo vo : data2) {
            Map<String, Integer> map = temp.get(vo.getMonth());
            map.put("land_specific_training", vo.getCompletionTime());
        }

        Map<String, Object> ret = new HashMap<>();
        List<String> annualPlan = new ArrayList<>();
        List<Integer> specialTrainingWater = new ArrayList<>();
        List<Integer> landSpecificTraining = new ArrayList<>();
        for (String key : temp.keySet()) {
            annualPlan.add(key);
            waterSpecialTotalKil += temp.get(key).get("special_training_water");
            landSpecialTotalKil += temp.get(key).get("land_specific_training");
            specialTrainingWater.add(temp.get(key).get("special_training_water"));
            landSpecificTraining.add(temp.get(key).get("land_specific_training"));
        }
        ret.put("annual_plan", annualPlan);
        ret.put("waterSpecialTotalKil", waterSpecialTotalKil);
        ret.put("landSpecialTotalKil", landSpecialTotalKil);
        ret.put("special_training_water", specialTrainingWater);
        ret.put("land_specific_training", landSpecificTraining);
        return ret;
    }

    @Override
    public Map<String, Object> getLandBoatData(int teamId) {
        //初始化默认数据
        Map<String, Long> map = getBoatTypeEmum();
        Map<String, Object> params = new HashMap<> ();
        params.put("naturalYearId",naturalYearService.getNaturalYearByDate(new Date()).getId());
        List<Map<String, Object>> list = this.trainingAchievementService.selectKilometersBoatType(params);
        for(Map<String, Object> ret : list){
            if(ret.get("boatType")!=null){
                map.put(ret.get("boatType").toString(),Long.parseLong(ret.get("kilometers").toString()));
            }
        }

        List<Long> maleValues = new ArrayList<>();
        List<Long> femaleValues = new ArrayList<>();
        //排序
        List<String> temp = new ArrayList<String>(map.keySet());
        Collections.sort(temp);
        for(String key : temp){
            if(key.startsWith("M-") || key.startsWith("M ")) {
                maleValues.add(map.get(key)==null ? 0L : map.get(key));
            }
            if(key.startsWith("W-") || key.startsWith("W ")) {
                femaleValues.add(map.get(key)==null ? 0L : map.get(key));
            }
        }

        /*maleValues.add(map.get("M 2X")==null ? 0L : map.get("M 2X"));
        femaleValues.add(map.get("W 2X")==null ? 0L : map.get("W 2X"));

        maleValues.add(map.get("M 2-")==null ? 0L : map.get("M 2-"));
        femaleValues.add(map.get("W 2-")==null ? 0L : map.get("W 2-"));

        maleValues.add(map.get("M 4X")==null ? 0L : map.get("M 4X"));
        femaleValues.add(map.get("W 4X")==null ? 0L : map.get("W 4X"));

        maleValues.add(map.get("M 4-")==null ? 0L : map.get("M 4-"));
        femaleValues.add(map.get("W 4-")==null ? 0L : map.get("W 4-"));

        maleValues.add(map.get("M 8+")==null ? 0L : map.get("M 8+"));
        femaleValues.add(map.get("W 8+")==null ? 0L : map.get("W 8+"));*/


        Map<String, Object> landBoatData = new HashMap<>();
        landBoatData.put("teamId", 1);
        landBoatData.put("teamName", "赛艇队");
        landBoatData.put("maleValue", maleValues);
        landBoatData.put("femaleValue", femaleValues);
        return landBoatData;
    }

    /**
     * 获取艇种的枚举值
     * @return
     */
    private Map<String, Long> getBoatTypeEmum() {
        Map<String, Long> boat = new HashMap<>();
        List<SysDictData> list = sysDictDataService.selectDictDataByType("type_boat_support");
        for (SysDictData sysDictData : list) {
            boat.put(sysDictData.getDictValue(), 0L);
        }
        return boat;
    }

    @Override
    public Map<String, Object> getTeamInfo(int teamId) {
        Map<String, Object> ret = new HashMap<>();
        Sportsman params = new Sportsman();
        List<Sportsman> sportsmanList = sportsmanService.selectSportsmanList(params);
        Map<String, Integer> educationMap = new HashMap<>();
        Map<String, Integer> transportUnit = new HashMap<>();

        int ageTotal = 0;
        int averageTraningYearTotal = 0;

        for (Sportsman sportsman : sportsmanList) {
            Integer index = educationMap.get(sportsman.getEducation());
            if (index == null) {
                index = 0;
            }
            educationMap.put(sportsman.getEducation(), ++index);

            Integer conveyingUnitCount = transportUnit.get(sportsman.getConveyingUnit());
            if (conveyingUnitCount == null) {
                conveyingUnitCount = 0;
            }
            transportUnit.put(sportsman.getConveyingUnit(), ++conveyingUnitCount);

            ageTotal += getAge(sportsman.getBirthday());
            averageTraningYearTotal += getAge(sportsman.getTrainingTime());
        }

        List<Map<String, Object>> educationList = new ArrayList<>();
        for (String key : educationMap.keySet()) {
            Map<String, Object> temp = new HashMap<>();
            temp.put("name", key);
            temp.put("value", educationMap.get(key));
            educationList.add(temp);
        }

        List<Map<String, Object>> transportUnitList = new ArrayList<>();
        for (String key : transportUnit.keySet()) {
            if(StringUtils.isNotEmpty(key)){
                Map<String, Object> temp = new HashMap<>();
                temp.put("name", key);
                temp.put("value", transportUnit.get(key));
                transportUnitList.add(temp);
            }
        }

        ret.put("teamId", 1);
        ret.put("teamName", "赛艇队");
        ret.put("averageTraningYears", averageTraningYearTotal / sportsmanList.size());
        ret.put("averageAge", ageTotal / sportsmanList.size());
        ret.put("education", educationList);
        ret.put("transportUnit", transportUnitList);
        return ret;
    }

    private int getAge(Date birthDay) {
        int age = 0;   //计算整岁数
        try {
            Calendar cal = Calendar.getInstance();
            if (cal.before(birthDay)) { //出生日期晚于当前时间，无法计算
                return 0;
            }
            int yearNow = cal.get(Calendar.YEAR);  //当前年份
            int monthNow = cal.get(Calendar.MONTH);  //当前月份
            int dayOfMonthNow = cal.get(Calendar.DAY_OF_MONTH); //当前日期
            cal.setTime(birthDay);
            int yearBirth = cal.get(Calendar.YEAR);
            int monthBirth = cal.get(Calendar.MONTH);
            int dayOfMonthBirth = cal.get(Calendar.DAY_OF_MONTH);
            age = yearNow - yearBirth;
            if (monthNow <= monthBirth) {
                if (monthNow == monthBirth) {
                    if (dayOfMonthNow < dayOfMonthBirth) age--;//当前日期在生日之前，年龄减一
                } else {
                    age--;//当前月份在生日之前，年龄减一
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
        return age;
    }
}
